package com.itcncp.wechat.app.mini.controller;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.itcncp.common.base.BaseController;
import com.itcncp.common.model.OrderCodeType;
import com.itcncp.common.util.DateUtils;
import com.itcncp.common.util.JsonUtils;
import com.itcncp.common.util.OrderUtils;
import com.itcncp.wechat.app.common.constant.ApiConstant;
import com.itcncp.wechat.app.common.constant.ApiResult;
import com.itcncp.wechat.app.common.constant.ApiResultConstant;
import com.itcncp.wechat.app.dao.model.UserCustomerInfo;
import com.itcncp.wechat.app.dao.model.UserRechangeOpJnl;
import com.itcncp.wechat.app.dao.model.UserRechangeOpJnlExample;
import com.itcncp.wechat.app.rpc.api.UserCustomerInfoService;
import com.itcncp.wechat.app.rpc.api.UserRechangeOpJnlService;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
/**
 *
 * Created by shuitcncp on 2016/12/10.
 */
@Controller
@RequestMapping("/recharge")
@Api(tags = "充值管理",value = "用户充值", description = "充值接口",
        produces = "produces",consumes = "consumes",basePath = "/recharge")

public class UserRechargeController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserRechargeController.class);

    @Autowired
    private UserCustomerInfoService userCustomerInfoService;
    @Autowired
    private UserRechangeOpJnlService userRechangeOpJnlService;


    /**
     * 微信充值
     * @param
     * @return
     */
    @ResponseBody
    @ApiOperation(value="微信充值",notes="充值金额单位 分 计算")
    @RequestMapping(value = "/wxPayRecharge", method = RequestMethod.POST)
    @ApiImplicitParams( value = {
            @ApiImplicitParam(paramType = "query", name = "userId", dataType = "Long", required = true, value = "用户ID"),
            @ApiImplicitParam(paramType = "query", name = "amount", dataType = "Integer", required = false, value = "充值金额金额 分")
    })
    public  Object wxPayRecharge(HttpServletRequest request,
                                    @RequestParam(required = true, value = "userId") Long userId,
                                    @RequestParam(required = true, value = "amount") Integer amount ) {


        //用戶id不能爲空
        if(userId<=0){
            return new ApiResult( ApiResultConstant.APP_ILLEGAL);
        }

        //充值金額不得小於0
        if(amount.doubleValue()<=0){
            return new ApiResult( ApiResultConstant.FAILED);
        }

        UserCustomerInfo userCustomerInfo = userCustomerInfoService.selectByPrimaryKey(userId);

        if(null == userCustomerInfo){
            return  new ApiResult( ApiResultConstant.APP_OPENID_EXPIRED);
        }

        String openid = userCustomerInfo.getDeviceAppNo();

        String orderNO = OrderUtils.createOrderId(OrderCodeType.RECHARGE_NO).toString();


        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();

        try {
            WxPayConfig wxPayConfig = new WxPayConfig();
            wxPayConfig.setAppId(ApiConstant.WX_MINI_APPID);
            wxPayConfig.setMchId(ApiConstant.WX_MINI_MCH_ID);
            wxPayConfig.setMchKey(ApiConstant.WX_MINI_MCH_KEY);
            wxPayConfig.setNotifyUrl(ApiConstant.WX_MINI_PAY_NOTIFYURL);
            wxPayConfig.setTradeType("JSAPI");

            WxPayService wxPayService = new WxPayServiceImpl();
            wxPayService.setConfig(wxPayConfig);

            orderRequest.setBody("ITC不停车收费余额充值");
            orderRequest.setOutTradeNo(orderNO.toString());
            orderRequest.setTotalFee(amount);
            orderRequest.setSpbillCreateIp(ApiConstant.WX_MINI_PAY_SPBILLCREATEIP);
            orderRequest.setOpenid(openid);
            orderRequest.setTimeStart(DateUtils.dateFormatNow("yyyyMMddHHmmss"));
            orderRequest.setTimeExpire(DateUtils.dateFormat(DateUtils.getAfterMinute(2),"yyyyMMddHHmmss"));

            WxPayMpOrderResult orderpay = wxPayService.createOrder(orderRequest);

            System.err.println("支付请求"+ JsonUtils.toJson(orderpay));

            //保存订单推送 prepay_id
            /**
             * 支付请求{"appId":"wx3aeb995e0e36f951","timeStamp":"1522319555","nonceStr":"15223
             19555101","packageValue":"prepay_id\u003dwx2018032918323420b19eff850964198546","
             signType":"MD5","paySign":"A50EFC346B26608C6C130C8600A9C16A"}
             */
            String packageValue = orderpay.getPackageValue();


            if(null != orderRequest) {
                //创建保存充值订单
                UserRechangeOpJnl userRechangeOpJnl = (UserRechangeOpJnl) userRechangeOpJnlService.wxMiniRechargeAmount(orderNO,userId,new BigDecimal(amount),packageValue);

                //保存充值订单
                System.err.println("保存充值订单"+ JsonUtils.toJson(userRechangeOpJnl));

                userRechangeOpJnl.setWxPayMpOrderResult(orderpay);

                return new ApiResult( ApiResultConstant.SUCCESS,userRechangeOpJnl);
            }else{
                return new ApiResult( ApiResultConstant.FAILED,"订单保存失败");
            }

        } catch (Exception e) {
            LOGGER.error("微信支付失败！订单号：{},原因:{}", orderNO.toString(), e.getMessage());
            System.err.println("微信支付失败！订单号："+ orderNO.toString()+",原因:"+e.getMessage());
            return new ApiResult( ApiResultConstant.FAILED,"支付失败，请稍后重试！");
        }

    }

    /**
     * 银行卡充值
     * @param
     * @return
     */
    @ResponseBody
    @ApiOperation(value="银行卡充值",notes="需要提供银行卡相关信息，充值金额单位 分")
    @RequestMapping(value = "/bankCarRecharge", method = RequestMethod.POST)
    @ApiImplicitParams( value = {
            @ApiImplicitParam(paramType = "query", name = "userId", dataType = "Long", required = true, value = "用户ID"),
            @ApiImplicitParam(paramType = "query", name = "amount", dataType = "BigDecimal", required = true, value = "提现总金额，包含手续费"),
            @ApiImplicitParam(paramType = "query", name = "bankcardNo", dataType = "String", required = true, value = "卡号"),
            @ApiImplicitParam(paramType = "query", name = "bankId", dataType = "String", required = true, value = "开户银行编号"),
            @ApiImplicitParam(paramType = "query", name = "mobile", dataType = "String", required = true, value = "手机号"),
            @ApiImplicitParam(paramType = "query", name = "authName", dataType = "String", required = true, value = "真实姓名"),
            @ApiImplicitParam(paramType = "query", name = "bankcardType", dataType = "String", required = true, value = "银行卡类型, 1-借记卡, 2-贷记卡, 3-准贷记卡, 4-预付费卡 \n" +
                    " 5-其他")
    })
    public  Object bankCarRecharge(HttpServletRequest request,
                                  @RequestParam(required = true,defaultValue = "",value = "userId") Long userId,
                                  @RequestParam(required = true,defaultValue = "",value = "amount") BigDecimal amount,
                                   @RequestParam(required = true, defaultValue = "", value = "bankcardNo") String bankcardNo,
                                   @RequestParam(required = true, defaultValue = "", value = "bankId") String bankId,
                                   @RequestParam(required = true, defaultValue = "", value = "mobile") String mobile,
                                   @RequestParam(required = true, defaultValue = "", value = "authName") String authName,
                                   @RequestParam(required = true, defaultValue = "", value = "bankcardType") Integer bankcardTyp) {


        //用戶id不能爲空
        if(userId<=0){
            return new ApiResult( ApiResultConstant.APP_ILLEGAL);
        }

        //充值金額不得小於0
        if(amount.doubleValue()<=0){
            return new ApiResult( ApiResultConstant.FAILED);
        }

        Object userAccountInfo = userRechangeOpJnlService.bankCardRechargeAmount(userId,amount);

        if(null != userAccountInfo){

            return new ApiResult( ApiResultConstant.SUCCESS,userAccountInfo);
        }

        return new ApiResult( ApiResultConstant.FAILED);
    }


    /**
     * 充值记录
     * @return
     */
    @ResponseBody
    @ApiOperation(value="充值记录",notes="查询出银行卡与微信等所有渠道的充值记录！")
    @RequestMapping(value = "/findRechargeList", method = RequestMethod.POST)
    @ApiImplicitParams( value = {
            @ApiImplicitParam(paramType = "query", name = "userId", dataType = "Long", required = true, value = "用户ID"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "Integer",
                    required = true,defaultValue = "1", value = "页数"),
            @ApiImplicitParam(paramType = "query", name = "pageIndex", dataType = "Integer",
                    required = true,defaultValue = "5",  value = "每页条数")
    })
    public Object findRechargeList(HttpServletRequest request,
                               @RequestParam(required = false, defaultValue = "", value = "userId") Long userId,
                               @RequestParam(required = false, defaultValue = "0", value = "pageSize") int pageSize,
                               @RequestParam(required = false, defaultValue = "5", value = "pageIndex") int pageIndex){


        if(userId <= 0){
            return new ApiResult( ApiResultConstant.APP_ILLEGAL );
        }

        UserRechangeOpJnlExample userRechangeOpHisExample = new UserRechangeOpJnlExample();
        userRechangeOpHisExample.createCriteria().andUserIdEqualTo( userId );

        //排序
        userRechangeOpHisExample.setOrderByClause("recharge_no desc");
        //分页查询
        List<UserRechangeOpJnl> userRechangeOpHis = userRechangeOpJnlService
                .selectByExampleForStartPage(userRechangeOpHisExample, pageSize, pageIndex);

        return new ApiResult( ApiResultConstant.SUCCESS,userRechangeOpHis);
    }

    /**
     * 根据订单号获取充值详情
     * @return
     */
    @ResponseBody
    @ApiOperation(value="充值详情",notes="单笔金额的充值详情")
    @RequestMapping(value = "/getRechargeOrderNo", method = RequestMethod.POST)
    @ApiImplicitParams( value = {
            @ApiImplicitParam(paramType = "query", name = "orderNo", dataType = "Long", required = true, value = "充值订单号")
    })
    public Object getRechargeOrderNo(HttpServletRequest request,
                                   @RequestParam(required = false, defaultValue = "0", value = "orderNo") Long orderNo){


        UserRechangeOpJnl userRechangeOpHis = userRechangeOpJnlService.selectByPrimaryKey( orderNo  );

        if(null!=userRechangeOpHis){
            return  new ApiResult( ApiResultConstant.SUCCESS,userRechangeOpHis);
        }

        return new ApiResult( ApiResultConstant.FAILED);
    }

    @ResponseBody
    @ApiOperation(value="充值结果查询",notes="充值结果查询")
    @RequestMapping(value = "/getRechargeOrderNoStatus", method = RequestMethod.POST)
    @ApiImplicitParams( value = {
            @ApiImplicitParam(paramType = "query", name = "userId", dataType = "Long", required = true, value = "用户ID"),
            @ApiImplicitParam(paramType = "query", name = "orderNo", dataType = "Long", required = false, value = "订单号")
    })
    public  Object getRechargeOrderNoStatus(HttpServletRequest request,
                                 @RequestParam(required = true, value = "userId") Long userId,
                                 @RequestParam(required = true, value = "orderNo") Long orderNo ) {


        UserRechangeOpJnl userRechangeOpHis = userRechangeOpJnlService.selectByPrimaryKey( orderNo  );

        //判断订单是否存在
        if(null==userRechangeOpHis){
            return  new ApiResult( ApiResultConstant.FAILED);
        }

        //判断订单会否已处理
        if(userRechangeOpHis.getRechargeState()==2){
            return  new ApiResult( ApiResultConstant.SUCCESS);
        }

        WxPayConfig wxPayConfig = new WxPayConfig();
        wxPayConfig.setAppId(ApiConstant.WX_MINI_APPID);
        wxPayConfig.setMchId(ApiConstant.WX_MINI_MCH_ID);
        wxPayConfig.setMchKey(ApiConstant.WX_MINI_MCH_KEY);
        wxPayConfig.setNotifyUrl(ApiConstant.WX_MINI_PAY_NOTIFYURL);
        wxPayConfig.setTradeType("JSAPI");

        WxPayService wxPayService = new WxPayServiceImpl();
        wxPayService.setConfig(wxPayConfig);

        try {
            WxPayOrderQueryResult wxPayOrderQueryResult = wxPayService.queryOrder("",orderNo.toString());

            /**
             *   SUCCESS—支付成功

             REFUND—转入退款

             NOTPAY—未支付

             CLOSED—已关闭

             REVOKED—已撤销（刷卡支付）

             USERPAYING--用户支付中

             PAYERROR--支付失败(其他原因，如银行返回失败)
             */
            String status = wxPayOrderQueryResult.getTradeState().toString();

            //微信支付订单号
            String transactionId = wxPayOrderQueryResult.getTransactionId();

            if(status.equals("SUCCESS")){

                //判断金额是否匹配
                if(userRechangeOpHis.getRechargeAmount().intValue()==wxPayOrderQueryResult.getCashFee()){

                    Object userAccountInfo = userRechangeOpJnlService.wxMiniRechargeCallBack(orderNo,transactionId);


                    return new ApiResult( ApiResultConstant.SUCCESS,userAccountInfo);
                }else{

                    return new ApiResult( ApiResultConstant.APP_WXPAY_NOT_FEE);

                }

            }else{
                if(status.equals("NOTPAY")){

                    return new ApiResult(ApiResultConstant.APP_WXPAY_NOTPAY);

                }else if(status.equals("USERPAYING")){

                    return new ApiResult(ApiResultConstant.APP_WXPAY_USERPAYING);

                }else if(status.equals("CLOSED")){

                    return new ApiResult(ApiResultConstant.APP_WXPAY_CLOSED);

                }else {

                    return new ApiResult(ApiResultConstant.APP_WXPAY_PAYERROR);
                }
            }

        } catch (WxPayException e) {

            return new ApiResult( 0,e.getMessage());

        }

    }

}